<?php
namespace app\data_magic\controller;

use cmf\controller\HomeBaseController;
use cmf\controller\AdminBaseController;
use app\data_magic\logic\Interpreter;
use app\data_magic\logic\Action;
use app\data_magic\struct\Input;
use app\data_magic\struct\Result;
use app\data_magic\struct\ListWidget;
use app\data_magic\struct\FormWidget;
use app\data_magic\struct\FilterWidget;
use app\data_magic\struct\TabsWidget;
use app\data_magic\logic\Field;

class DataUserController extends HomeBaseController
{
    public function open()
    {   
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        if(!$interpreter->access($user_id)->loadAction(input("action_id"))){
            $this->error($interpreter->getError());
        }
        $input=$this->loadInputParams($interpreter,input());
        $result=$interpreter->dispath($input);
        if($result->status===false){
            $message = $result->message ? $result->message : "操作失败" ;
            $this->error($message);
        }
        elseif($result->is_page===false){
            $message = $result->message ? $result->message : "操作成功" ;
            $result->redirect_params["action_id"]=$interpreter->action->bind_action["id"];
            $this->success($message,url("open",$result->redirect_params));
        }
        else{
            return $this->renderPage($interpreter->action,$input,$result);
        }
    }
    public function selectRefer()
    {
        $interpreter=new Interpreter();
        $user_id=cmf_get_current_user_id();
        if(!$interpreter->access($user_id,["admin"])->loadAction(input("action_id"))){
            $this->error($interpreter->getError());
        }
        $input=$this->loadInputParams($interpreter,input());
        $result=$interpreter->dispath($input);
        if($result->status===false){
            $message = $result->message ? $result->message : "操作失败" ;
            $this->error($message);
        }
        if($result->is_page===false){
            $this->error("设置错误");
        }
        foreach($result->widget as $struct){
            if($struct instanceof ListWidget){
                $data_list=$interpreter->action->paginate(10);
                $this->assign('paginate', $data_list->render());
                $struct->data_list=$data_list;
                $this->assign($struct->toArray());
                $this->assign("list_widget",$this->fetch("list"));
            }
        }
        $this->assign("selected_ids",input("ids"));
        return $this->fetch("refer");
    }
    /**
     * 加载输入参数
     * @param Interpreter $interpreter 解释器
     * @param array $input 输入值
     * @return Input
     */
    public function loadInputParams($interpreter,$input)
    {
        $action_input=new Input();
        if(isset($input["data_id"]) && $input["data_id"]){
            $action_input->pks=$input["data_id"];
            unset($input["data_id"]);
        }
        elseif(isset($input["data_ids"])){
            $pks=$input["data_ids"];
            if(is_array($pks)){
                $action_input->pks=implode(",",$pks);
            }
            elseif(is_string($pks)){
                $action_input->pks=$pks;
            }
            unset($input["data_ids"]);
        }
        if(isset($input["filter"]) && is_array($input["filter"])){
            $action_input->filter=$input["filter"];
            unset($input["filter"]);
        }
        $action_input->data=$this->convertInputData($interpreter,$input);
        return $action_input;
    }
    /**
     * 将字段编辑Widget输入的数据转换成内部数据
     * @param Interpreter $interpreter 解释器
     */
    public function convertInputData($interpreter,$item)
    {
        foreach($interpreter->fields as $field){
            $field_name=$field->name;
            if(!$field->writable){
                continue;
            }
            elseif(in_array($field->type,["select","radio","checkbox","refer"])){
                if(isset($item[$field_name]) && is_string($item[$field_name])){
                    $item[$field_name]=explode(",",$item[$field_name]);
                }
            }
            elseif(in_array($field->type,["datetime","date","time"])){
                if(isset($item[$field_name])){
                    $format_map=["datetime"=>"Y-m-d H:i","date"=>"Y-m-d","time"=>"H:i:s"];
                    $item[$field_name]=date_create_from_format($format_map[$field->type],$item[$field_name])->getTimestamp();
                }
            }
            elseif(in_array($field->type,["images","files"])){
                if(isset($item[$field_name."_urls"]) && isset($item[$field_name."_names"])){
                    $urls = $item[$field_name."_urls"];
                    $names = $item[$field_name."_names"];
                    $file_list=[];
                    foreach($urls as $index=>$url){
                        $file_list[] = [
                            "url"=>$url,
                            "name"=>isset($names[$index]) ? $names[$index] : ""
                        ];
                    }
                    $item[$field_name]=$file_list;
                }
            }
            elseif($field->type==="location"){
                if(isset($item[$field_name])){
                    $location = ["text"=>"","longitude"=>0,"latitude"=>0];
                    $location_params=explode(",",$item[$field_name]);
                    if(count($location_params)===2){
                        $location["longitude"]=$location_params[0];//经度
                        $location["latitude"]=$location_params[1];//纬度
                    }
                    if(isset($item[$field_name."_text"])){
                        $location["text"]=$item[$field_name."_text"];
                    }
                    $item[$field_name]=$location;
                }
            }
            elseif($field->type==="html"){
                if(isset($item[$field_name])){
                    $html=htmlspecialchars_decode($item[$field_name]);//将转码过的HTML代码恢复
                    $html=cmf_replace_content_file_url($html, true);//替换内容中的文件链接
                    $item[$field_name]=htmlspecialchars($html);//将HTML代码重新转码
                }
            }
        }
        return $item;
    }
    /**
     * 渲染页面
     * @param Action $action
     * @param Input $input
     * @param Result $result
     */
    public function renderPage($action,$input,$result)
    {
        foreach($result->widget as $struct){
            if($struct instanceof TabsWidget){
                $this->assign($struct->toArray());
                $this->assign("tabs_widget",$this->fetch("tabs"));
            }
            elseif($struct instanceof FilterWidget){
                $this->assign($struct->toArray());
                $this->assign("filter_widget",$this->fetch("filters"));
            }
            elseif($struct instanceof ListWidget){
                $data_list=$action->paginate(10);
                $this->assign('paginate', $data_list->render());
                $struct->data_list=$data_list;
                $this->assign($struct->toArray());
                $this->assign("list_widget",$this->fetch("list"));
            }
            elseif($struct instanceof FormWidget){
                $data_type=$action->action["data_type"];
                $action_type=$action->action["action_type"];
                if($data_type==="single"){
                    $struct->data_item=$action->find();
                }
                if($action_type==="update"){
                    if($data_type==="single") $struct->hidden["data_id"]=$input->pks;
                    elseif($data_type==="multi") $struct->hidden["data_ids"]=$input->pks;
                    else{
                        $list=$action->select();
                        $pks=[];
                        foreach($list as $item){
                            $pks[]=$item[$action->scene->primary_key];
                        }
                        $pks=implode(",",$pks);
                        $hidden["data_ids"]=$pks;
                    }
                }
                $this->assign($struct->toArray());
                $this->assign("form_widget",$this->fetch("form"));
            }
        }
        return $this->fetch("page");
    }
}
